package com.zrf.testchatgpt.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrf.testchatgpt.entity.Admin;
import com.zrf.testchatgpt.entity.vo.UserVo;
import com.zrf.testchatgpt.entity.Users;
import com.zrf.testchatgpt.shiro.util.JwtTokenUtil;
import com.zrf.testchatgpt.shiro.token.LoginToken;
import com.zrf.testchatgpt.mapper.UsersMapper;
import com.zrf.testchatgpt.constant.Constant;
import com.zrf.testchatgpt.shiro.util.ShiroUtils;
import com.zrf.testchatgpt.util.RedisCacheUtil;
import com.zrf.testchatgpt.util.Result;
import com.zrf.testchatgpt.util.WeiXinUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zrf
 * @since 2023-03-15
 */
@RestController
@Slf4j
@RequestMapping("/User")
public class UsersController {

    @Autowired
    private WeiXinUtil weiXinUtil;

    @Autowired
    RedisCacheUtil redisCacheUtil;

    @Autowired
    JwtTokenUtil jwtUtil;
    @Autowired
    ShiroUtils shiroUtils;
    @Resource
    private UsersMapper usersMapper;
    @RequestMapping("/insertOpinID")
    public Result InsertOpinID( Users tbAnsweUser) {
        if (StrUtil.isBlank(tbAnsweUser.getJs_code())) {
            return new Result("500","请求参数为空",null);
        }
        JSONObject jsonObject = weiXinUtil.getSessionkey(tbAnsweUser.getJs_code());
        String session_key = jsonObject.getStr("session_key");
        String openid = jsonObject.getStr("openid");
        LambdaQueryWrapper<Users> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Users::getUserOpenid,openid);
        //根据openID去查询,看是否存在该用户
        Users tbAnsweUserSelect = usersMapper.selectOne(wrapper);
        if (Objects.isNull(tbAnsweUserSelect)) {
            tbAnsweUserSelect = tbAnsweUser;
            if (StrUtil.isBlank(tbAnsweUserSelect.getWxName())) {
                return new Result("500","用户名为空",null);
            }
            if (StrUtil.isBlank(tbAnsweUserSelect.getHeadImage())) {
                return new Result("500","头像为空",null);

            }
            //初始化回答次数
            tbAnsweUserSelect.setUserOpenid(openid);
            tbAnsweUserSelect.setUserAnswerNum(5);
            tbAnsweUserSelect.setCreateTime(WeiXinUtil.getTime());
//            if(!redisCache.hasKey(token))
//                redisCache.setCacheObject(token,"true",60*24, TimeUnit.MINUTES);
          usersMapper.insert(tbAnsweUserSelect);
        }
        Map<String,Object> map=new HashMap<>();
        map.put(Constant.JWT_TOKEN_USERNAME,tbAnsweUserSelect.getWxName());
        map.put(Constant.JWT_TOKEN_OPENID,openid);
//        map.put(Constant.ROLES_INFOS_KEY,"admin");
//        map.put(Constant.PERMISSIONS_INFOS_KEY,"admin:select");
        String accessToken = jwtUtil.getAccessToken("admin", map);
        String refreshToken = jwtUtil.getRefreshToken("admin", map);
        tbAnsweUserSelect.setAccessToken(accessToken);
        tbAnsweUserSelect.setRefreshToken(refreshToken);
        LoginToken loginToken=new LoginToken(tbAnsweUser.getWxName(),openid);
//        UsernamePasswordToken loginToken=new UsernamePasswordToken(tbAnsweUserSelect.getWxName(),openid);
        Subject subject = SecurityUtils.getSubject();
        subject.login(loginToken);
        String sessionid = (String) subject.getSession(true).getId();
        tbAnsweUserSelect.setSessionId(sessionid);
        return new Result("200","成功",tbAnsweUserSelect);
    }
    @GetMapping("/logout")
    public Result result( HttpServletRequest httpRequest){

        String accessstoken = httpRequest.getHeader("accesstoken");
        String refreshtoken = httpRequest.getHeader("refreshtoken");
        String userName="";
        if (accessstoken!=null)
         userName = jwtUtil.getUserName(accessstoken);
        //如果header中不存在token，则从参数中获取token
        if(StringUtils.isBlank(accessstoken)){
            accessstoken = httpRequest.getParameter("accessstoken");
        }
        if(!StringUtils.isBlank(accessstoken))
        redisCacheUtil.setCacheObject(Constant.JWT_ACCESS_TOKEN_BLACKLIST+accessstoken,userName,  jwtUtil.getRemainingTime(accessstoken),TimeUnit.MILLISECONDS);
        if(StringUtils.isBlank(refreshtoken)){
            refreshtoken = httpRequest.getParameter("refreshtoken");
        }
        if(!StringUtils.isBlank(refreshtoken))
        redisCacheUtil.setCacheObject(Constant.JWT_REFRESH_TOKEN_BLACKLIST+refreshtoken,userName,  jwtUtil.getRemainingTime(refreshtoken),TimeUnit.MILLISECONDS);
        String userId = httpRequest.getParameter("userId");
        shiroUtils.deleteCache(userId,true);
        return  Result.builder().code("200").msg("退出登录成功").build();
    }
    @PostMapping("/reloadtoken")
    public Result reloadtoken(HttpServletRequest request){
        String refreshtoken = request.getHeader("refreshtoken");
        String accesstoken = request.getHeader("accesstoken");
        if(StringUtils.isBlank(refreshtoken)){
            refreshtoken = request.getParameter("refreshtoken");
        }
        String userName = jwtUtil.getUserName(refreshtoken);
        if (!StringUtils.isBlank(accesstoken)){
            redisCacheUtil.setCacheObject(Constant.JWT_ACCESS_TOKEN_BLACKLIST+accesstoken,userName,  jwtUtil.getRemainingTime(accesstoken),TimeUnit.MILLISECONDS);
        }
        if (!jwtUtil.validateToken(refreshtoken)|| redisCacheUtil.hasKey(Constant.JWT_REFRESH_TOKEN_BLACKLIST+refreshtoken)){
            return Result.builder().code("500").msg("refreshtoken 失效").build();
        }
        String userId = jwtUtil.getUserId(refreshtoken);
        String openid = (String) jwtUtil.getInfoByKey(refreshtoken, "openid");
        Map<String,Object> map=new HashMap<>();
        map.put(Constant.JWT_TOKEN_USERNAME,userName);
        map.put(Constant.JWT_TOKEN_OPENID,openid);
        String accessToken = jwtUtil.getAccessToken(userId, map);
        return Result.builder().code("200").msg("成功").data(accessToken).build();
    }
    @GetMapping("/checkIsIng")
    public Boolean checkIsIng(String answeUserOpenid) {
       // Object o = redisTemplate.opsForValue().get(answeUserOpenid);
//        if (Objects.isNull(o)) {
//            return false;
//        }
        return false;
    }
    @RequestMapping("/unauth")
    public Map<String,Object> unauth(){
        Map<String,Object> map = new HashMap<>();
        map.put("code",500);
        map.put("msg","未登录");
        return map;
    }

    @PostMapping("login")
    public Result login(@RequestBody Admin admin){
        Map<String,Object> map=new HashMap<>();
//        List<String> list=new ArrayList<>();
//        list.add("admin");
        LambdaQueryWrapper<Users> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Users::getWxName,admin.getUsername());
        wrapper.eq(Users::getWxPhone,admin.getPassword());
        Users users = usersMapper.selectOne(wrapper);
        LoginToken loginToken=new LoginToken(users.getWxName(),users.getUserOpenid());
        Subject subject = SecurityUtils.getSubject();
        subject.login(loginToken);

        if (users!=null) {
            map.put("roles", "admin");
            map.put("avatar", users.getHeadImage());
            map.put("name", admin.getUsername());
            String token = jwtUtil.getAccessToken("admin", map);
            return Result.builder().code("200").data(token).build();
        }else{
            return Result.builder().code("500").msg("用户名或密码错误").build();
        }
    }

    @GetMapping("info")
    public Result getinfo(@RequestParam String accesstoken){
        String roles = (String) jwtUtil.getInfoByKey(accesstoken, "roles");
        String avatar = (String) jwtUtil.getInfoByKey(accesstoken, "avatar");
        String name= (String) jwtUtil.getInfoByKey(accesstoken,"name");
        Map<String,Object> map=new HashMap<>();
        map.put("roles",roles);
        map.put("avatar",avatar);
        map.put("name",name);
        return Result.builder().code("200").data(map).build();
    }

    @GetMapping("getUser")
    public Result getAllUser(String username,Integer current,Integer size){

        LambdaQueryWrapper<Users> wrapper=new LambdaQueryWrapper<>();
        wrapper.like(Users::getWxName,username);
        IPage<Users> page = new Page<>(current, size);
        usersMapper.selectPage(page, wrapper);
        UserVo userVo =  UserVo.builder().current(current).size(size).total(page.getTotal()).userList(page.getRecords()).
                build();
        if (page.getTotal()>0){
            return Result.builder().code("200").data(userVo).msg("查询成功!!").build();
        }
        return Result.builder().code("500").data(null).msg("查询为空!!").build();
    }

}


